home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Harvest C 1.3 / Source Code / dumpmpw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  21.2 KB  |  909 lines  |  [TEXT/ALFA]

  1. /*
  2.     Harvest C
  3.     Copyright 1992 Eric W. Sink.  All rights reserved.
  4.     
  5.     This file is part of Harvest C.
  6.     
  7.     Harvest C is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU Generic Public License as published by
  9.     the Free Software Foundation; either version 2, or (at your option)
  10.     any later version.
  11.     
  12.     Harvest C is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.     
  17.     You should have received a copy of the GNU General Public License
  18.     along with Harvest C; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.     
  21.     Harvest C is not in any way a product of the Free Software Foundation.
  22.     Harvest C is not GNU software.
  23.     Harvest C is not public domain.
  24.  
  25.     This file may have other copyrights which are applicable as well.
  26.  
  27. */
  28.  
  29. /*
  30.  * Harvest C
  31.  * 
  32.  * Copyright 1991 Eric W. Sink   All rights reserved.
  33.  * 
  34.  * This file contains routines for dumping 68k assembly code records as MPW
  35.  * Object records.
  36.  * 
  37.  * 
  38.  * 
  39.  */
  40.  
  41.  
  42. #include "conditcomp.h"
  43. #include <stdio.h>
  44. #include <string.h>
  45. #include "structs.h"
  46.  
  47. #pragma segment DumpOMF
  48.  
  49.  
  50. /* While creating Contents records, the results are built here. */
  51. static EString_t                DATAContentsBuffer = NULL;
  52. static long                     DATAContentsIndex;
  53. static EString_t                CODEContentsBuffer = NULL;
  54. static long                     CODEContentsIndex;
  55. static int                      CurMPWSegNum;
  56.  
  57. /* MPW Record routines */
  58.  
  59. static short                    MPWSeg;
  60. static unsigned short           NextMPWID = 1;
  61. MPWListVia_t                    GlobalRecords;
  62. MPWDictListVia_t                OBJNameList;
  63.  
  64. MPWDictListVia_t
  65. RawMPWDictList(void)
  66. {
  67.     MPWDictListVia_t                raw;
  68.     raw = Ealloc(sizeof(MPWDictList_t));
  69.     Via(raw)->head = NULL;
  70.     Via(raw)->tail = NULL;
  71.     Via(raw)->count = 0;
  72.     return raw;
  73. }
  74.  
  75. MPWDictVia_t
  76. RawMPWDict(char *name)
  77. {
  78.     MPWDictVia_t                    raw;
  79.     raw = Ealloc(sizeof(MPWDict_t) + strlen(name));
  80.     Via(raw)->DictID = 0;
  81.     Via(raw)->isEXTERNAL = 0;
  82.     Via(raw)->next = NULL;
  83.     strcpy(Via(raw)->name, name);
  84.     return raw;
  85. }
  86.  
  87. MPWListVia_t
  88. RawMPWList(void)
  89. {
  90.     MPWListVia_t                    raw;
  91.     raw = Ealloc(sizeof(MPWList_t));
  92.     Via(raw)->head = NULL;
  93.     Via(raw)->tail = NULL;
  94.     Via(raw)->count = 0;
  95.     return raw;
  96. }
  97.  
  98. MPWRecordVia_t
  99. RawMPWRecord(void)
  100. {
  101.     MPWRecordVia_t                  raw;
  102.     raw = Ealloc(sizeof(MPWRecord_t));
  103.     Via(raw)->RecordType = 0;
  104.     Via(raw)->theRecord = NULL;
  105.     Via(raw)->next = NULL;
  106.     Via(raw)->recsize = 0;
  107.     return raw;
  108. }
  109.  
  110. void
  111. KillMPWRecord(MPWRecordVia_t rec)
  112. {
  113.     if (rec) {
  114.     Efree(Via(rec)->theRecord);
  115.     Efree(rec);
  116.     }
  117. }
  118.  
  119. void
  120. KillRecordsList(MPWListVia_t reclist)
  121. {
  122.     MPWRecordVia_t                  cur;
  123.     MPWRecordVia_t                  nxt;
  124.     if (reclist) {
  125.     cur = Via(reclist)->head;
  126.     while (cur) {
  127.         nxt = Via(cur)->next;
  128.         KillMPWRecord(cur);
  129.         cur = nxt;
  130.     }
  131.     Via(reclist)->head = NULL;
  132.     Via(reclist)->tail = NULL;
  133.     Via(reclist)->count = 0;
  134.     }
  135. }
  136.  
  137. void
  138. KillMPWDict(MPWDictVia_t rec)
  139. {
  140.     if (rec) {
  141.     Efree(rec);
  142.     }
  143. }
  144.  
  145. void
  146. KillDictList(MPWDictListVia_t Dicts)
  147. {
  148.     MPWDictVia_t                    cur;
  149.     MPWDictVia_t                    nxt;
  150.     if (Dicts) {
  151.     cur = Via(Dicts)->head;
  152.     while (cur) {
  153.         nxt = Via(cur)->next;
  154.         KillMPWDict(cur);
  155.         cur = nxt;
  156.     }
  157.     Efree(Dicts);
  158.     }
  159. }
  160.  
  161. MPWDictVia_t
  162. FindDict(char *name, MPWDictListVia_t Dicts)
  163. {
  164.     MPWDictVia_t                    cur;
  165.     cur = Via(Dicts)->head;
  166.     while (cur) {
  167.     if (!strcmp(name, (Via(cur)->name)))
  168.         return cur;
  169.     cur = Via(cur)->next;
  170.     }
  171.     return NULL;
  172. }
  173.  
  174. void
  175. DoWord(unsigned char *buf, long x)
  176. {
  177.     buf[0] = x >> 8;
  178.     buf[1] = x;
  179. }
  180.  
  181. void
  182. DoLong(unsigned char *buf, long x)
  183. {
  184.     buf[0] = x >> 24;
  185.     buf[1] = x >> 16;
  186.     buf[2] = x >> 8;
  187.     buf[3] = x;
  188. }
  189.  
  190. void
  191. AddMPWRec(MPWRecordVia_t rec, MPWListVia_t Records)
  192. {
  193.     if (Pass == 1) {
  194.     if (rec)
  195.         KillMPWRecord(rec);
  196.     return;
  197.     }
  198.     if (!rec)
  199.     return;
  200.     if (!Records)
  201.     return;
  202.     Via(rec)->next = NULL;
  203.     if (Via(Records)->head) {
  204.     Via(Records)->count++;
  205.     Via(Via(Records)->tail)->next = rec;
  206.     Via(Records)->tail = rec;
  207.     } else {
  208.     Via(Records)->head = rec;
  209.     Via(Records)->tail = rec;
  210.     Via(Records)->count = 1;
  211.     }
  212. }
  213.  
  214. #define RecType(x) { Via(rec)->RecordType =x; Via(Via(rec)->theRecord)[0] = x; }
  215. #define RecSize(x) {Via(rec)->recsize = x; Via(rec)->theRecord = Ealloc(x); }
  216.  
  217. void
  218. MPW_Comment(char *comment, MPWListVia_t Records)
  219. {
  220.     int                             len;
  221.     MPWRecordVia_t                  rec;
  222.     int                             ndx;
  223.  
  224.     rec = RawMPWRecord();
  225.     len = 4 + strlen(comment) + 1;
  226.     RecSize(len);
  227.     RecType(MPWRec_Comment);
  228. #ifdef OLDMEM
  229.     HLock((Handle) rec);
  230. #endif
  231.  
  232.     Via(Via(rec)->theRecord)[1] = 0;
  233.     DoWord(&(Via(Via(rec)->theRecord)[2]), len);
  234.     ndx = 4;
  235.     while (*comment) {
  236.     Via(Via(rec)->theRecord)[ndx++] = *comment;
  237.     comment++;
  238.     }
  239.     Via(Via(rec)->theRecord)[ndx] = 0;
  240. #ifdef OLDMEM
  241.     HUnlock((Handle) rec);
  242. #endif
  243.     AddMPWRec(rec, Records);
  244. }
  245.  
  246. void
  247. MPW_Last(MPWListVia_t Records)
  248. {
  249.     MPWRecordVia_t                  rec;
  250.     rec = RawMPWRecord();
  251.     RecSize(2);
  252.     RecType(MPWRec_Last);
  253.  
  254.     Via(Via(rec)->theRecord)[1] = 0;
  255.     AddMPWRec(rec, Records);
  256. }
  257.  
  258. void
  259. MPW_First(unsigned char FlagsByte, unsigned short Version, MPWListVia_t Records)
  260. {
  261.     MPWRecordVia_t                  rec;
  262.     rec = RawMPWRecord();
  263.     RecSize(4);
  264.     RecType(MPWRec_First);
  265. #ifdef OLDMEM
  266.     HLock((Handle) rec);
  267. #endif
  268.  
  269.     Via(Via(rec)->theRecord)[1] = FlagsByte;
  270.     DoWord(&(Via(Via(rec)->theRecord)[2]), Version);
  271. #ifdef OLDMEM
  272.     HUnlock((Handle) rec);
  273. #endif
  274.     AddMPWRec(rec, Records);
  275. }
  276.  
  277. void
  278. AddMPWDict(char *name, unsigned short ID, int isdefined, MPWDictListVia_t Dicts)
  279. {
  280.     MPWDictVia_t                    rec;
  281.     if (Pass == 1)
  282.     return;
  283.     rec = RawMPWDict(name);
  284.     Via(rec)->DictID = ID;
  285.     Via(rec)->isEXTERNAL = isdefined;
  286.     if (!Dicts)
  287.     return;
  288.     Via(rec)->next = NULL;
  289.     if (Via(Dicts)->head) {
  290.     Via(Dicts)->count++;
  291.     Via(Via(Dicts)->tail)->next = rec;
  292.     Via(Dicts)->tail = rec;
  293.     } else {
  294.     Via(Dicts)->head = rec;
  295.     Via(Dicts)->tail = rec;
  296.     Via(Dicts)->count = 1;
  297.     }
  298. }
  299.  
  300. void
  301. MPW_DoDictionary(unsigned char FlagsByte, char *name, int Defined,
  302.          unsigned short ID,
  303.          MPWListVia_t Records)
  304. {
  305.     MPWRecordVia_t                  rec;
  306.     int                             len;
  307.     int                             ndx;
  308.     if (FindDict(name, OBJNameList))
  309.     return;
  310.     rec = RawMPWRecord();
  311.     len = 7 + strlen((name));
  312.     RecSize(len);
  313.     RecType(MPWRec_Dictionary);
  314. #ifdef OLDMEM
  315.     HLock((Handle) rec);
  316. #endif
  317.  
  318.     Via(Via(rec)->theRecord)[1] = FlagsByte;
  319.     DoWord(&(Via(Via(rec)->theRecord)[2]), Via(rec)->recsize);
  320.     DoWord(&(Via(Via(rec)->theRecord)[4]), ID);
  321.     Via(Via(rec)->theRecord)[6] = strlen((name));
  322.     ndx = 0;
  323.     while (ndx < strlen((name))) {
  324.     Via(Via(rec)->theRecord)[7 + ndx] = (name)[ndx];
  325.     ndx++;
  326.     }
  327. #ifdef OLDMEM
  328.     HUnlock((Handle) rec);
  329. #endif
  330.     AddMPWRec(rec, Records);
  331.     AddMPWDict(name, NextMPWID - 1, Defined, OBJNameList);
  332. }
  333.  
  334. void
  335. MPW_Dictionary(unsigned char FlagsByte, char *name, int Defined,
  336.            MPWListVia_t Records)
  337. {
  338.     /*
  339.      * Generate a dictionary record, AND generate a dict entry for
  340.      * OBJNameList
  341.      */
  342.     MPW_DoDictionary(FlagsByte, name, Defined, NextMPWID++, Records);
  343. }
  344.  
  345. void
  346. MPW_Module(unsigned char FlagsByte, unsigned short ModID,
  347.        unsigned short ModSize, MPWListVia_t Records)
  348. {
  349.     MPWRecordVia_t                  rec;
  350.     rec = RawMPWRecord();
  351.     RecSize(6);
  352.     RecType(MPWRec_Module);
  353. #ifdef OLDMEM
  354.     HLock((Handle) rec);
  355. #endif
  356.  
  357.     Via(Via(rec)->theRecord)[1] = FlagsByte;
  358.     DoWord(&(Via(Via(rec)->theRecord)[2]), ModID);
  359.     DoWord(&(Via(Via(rec)->theRecord)[4]), ModSize);
  360. #ifdef OLDMEM
  361.     HUnlock((Handle) rec);
  362. #endif
  363.     AddMPWRec(rec, Records);
  364. }
  365.  
  366. void
  367. MPW_Size(unsigned char FlagsByte, long sizevalue, MPWListVia_t Records)
  368. {
  369.     MPWRecordVia_t                  rec;
  370.     rec = RawMPWRecord();
  371.     RecSize(6);
  372.     RecType(MPWRec_Size);
  373. #ifdef OLDMEM
  374.     HLock((Handle) rec);
  375. #endif
  376.  
  377.     Via(Via(rec)->theRecord)[1] = FlagsByte;
  378.     DoLong(&(Via(Via(rec)->theRecord)[2]), sizevalue);
  379. #ifdef OLDMEM
  380.     HUnlock((Handle) rec);
  381. #endif
  382.     AddMPWRec(rec, Records);
  383. }
  384.  
  385. void
  386. MPW_Contents(unsigned char FlagsByte, EString_t Buffer, long
  387.          BufferSize, MPWListVia_t Records)
  388. {
  389.     MPWRecordVia_t                  rec;
  390.     int                             ndx, ndx2;
  391.     rec = RawMPWRecord();
  392.     RecSize(4 + BufferSize);
  393.     RecType(MPWRec_Contents);
  394. #ifdef OLDMEM
  395.     HLock((Handle) rec);
  396. #endif
  397.  
  398.     Via(Via(rec)->theRecord)[1] = FlagsByte;
  399.     DoWord(&(Via(Via(rec)->theRecord)[2]), Via(rec)->recsize);
  400.     ndx = 0;
  401.     ndx2 = 4;
  402.     while (ndx < BufferSize) {
  403.     Via(Via(rec)->theRecord)[ndx2++] = Via(Buffer)[ndx++];
  404.     }
  405. #ifdef OLDMEM
  406.     HUnlock((Handle) rec);
  407. #endif
  408.     AddMPWRec(rec, Records);
  409. }
  410.  
  411. void
  412. MPW_Reference(unsigned char FlagsByte, unsigned short RefID, long
  413.           offset, MPWListVia_t Records)
  414. {
  415.     MPWRecordVia_t                  rec;
  416.     rec = RawMPWRecord();
  417.     RecSize(8);
  418.     RecType(MPWRec_Reference);
  419. #ifdef OLDMEM
  420.     HLock((Handle) rec);
  421. #endif
  422.  
  423.     Via(Via(rec)->theRecord)[1] = FlagsByte;
  424.     DoWord(&(Via(Via(rec)->theRecord)[2]), Via(rec)->recsize);
  425.     DoWord(&(Via(Via(rec)->theRecord)[4]), RefID);
  426.     DoWord(&(Via(Via(rec)->theRecord)[6]), offset);
  427. #ifdef OLDMEM
  428.     HUnlock((Handle) rec);
  429. #endif
  430.     AddMPWRec(rec, Records);
  431. }
  432.  
  433. unsigned short
  434. NameID(MPWDictListVia_t Dicts, char *name, unsigned char FlagsByte, int
  435.        isdefined, MPWListVia_t Records)
  436. {
  437.     /*
  438.      * If the name does not exist, generate a Dictionary record for it
  439.      */
  440.     MPWDictVia_t                    dict;
  441.     dict = FindDict(name, Dicts);
  442.     if (!dict) {
  443.     MPW_Dictionary(FlagsByte, name, isdefined, Records);
  444.     dict = FindDict(name, Dicts);
  445.     }
  446.     if (dict)
  447.     return Via(dict)->DictID;
  448.     else
  449.     return 0;
  450. }
  451.  
  452. unsigned char
  453. GetModuleFlags(char *name)
  454. {
  455.     MPWDictVia_t                    dict;
  456.     dict = FindDict(name, OBJNameList);
  457.     if (dict) {
  458.     if (Via(dict)->isEXTERNAL)
  459.         return 8;
  460.     else
  461.         return 0;
  462.     } else {
  463.     return 0;
  464.     }
  465. }
  466.  
  467. void
  468. WordAlignContents(void)
  469. {
  470.     if (MPWSeg) {        /* data */
  471.         if (DATAContentsIndex % 2)
  472.             if (Pass == 2)
  473.             DATAContentsIndex++;
  474.         Pc++;
  475.     } else {
  476.         if (CODEContentsIndex % 2)
  477.             if (Pass == 2)
  478.             CODEContentsIndex++;
  479.         Pc++;
  480.     }
  481. }
  482.  
  483. void
  484. AddContentsByte(unsigned char bt)
  485. {
  486.     if (Pass == 1)
  487.     return;
  488.     if (MPWSeg) {        /* data */
  489.     Via(DATAContentsBuffer)[DATAContentsIndex++] = bt;
  490.     } else {
  491.     Via(CODEContentsBuffer)[CODEContentsIndex++] = bt;
  492.     }
  493. }
  494.  
  495. void
  496. AddContentsWord(unsigned short wd)
  497. {
  498.     AddContentsByte(hibyte(wd));
  499.     AddContentsByte(lobyte(wd));
  500. }
  501.  
  502. void
  503. AddContentsLong(unsigned long wd)
  504. {
  505.     AddContentsWord(hiword(wd));
  506.     AddContentsWord(loword(wd));
  507. }
  508.  
  509. void
  510. FlushCode(MPWListVia_t Records)
  511. {
  512.     if (CODEContentsIndex) {
  513.     MPW_Contents(0, CODEContentsBuffer, CODEContentsIndex, Records);
  514.     CODEContentsIndex = 0;
  515.     }
  516. }
  517.  
  518. void
  519. FlushData(MPWListVia_t Records)
  520. {
  521.     if (DATAContentsIndex) {
  522.     MPW_Contents(1, DATAContentsBuffer, DATAContentsIndex, Records);
  523.     DATAContentsIndex = 0;
  524.     }
  525. }
  526.  
  527. void
  528. CodeModule(unsigned char FlagsByte, unsigned short ModID,
  529.        unsigned short ModSize, MPWListVia_t Records)
  530. {
  531.     FlushCode(Records);
  532.     MPW_Module(FlagsByte, ModID, ModSize, Records);
  533.     MPWSeg = 0;
  534.     Pc = 0;
  535. }
  536.  
  537. void
  538. DataModule(unsigned char FlagsByte, unsigned short ModID,
  539.        unsigned short ModSize, MPWListVia_t Records)
  540. {
  541.     FlushData(Records);
  542.     MPW_Module(FlagsByte | 1, ModID, ModSize, Records);
  543.     MPWSeg = 1;
  544. }
  545.  
  546. void
  547. AddtoContents(InstVia_t inst)
  548. {
  549.     int                             ndx;
  550.     if (Via(inst)->OP == M68op_DELETED) return;
  551.     ndx = 0;
  552.     if (Via(inst)->InstSize < 0)
  553.     return;
  554.     while (ndx < Via(inst)->InstSize) {
  555.     AddContentsByte(Via(inst)->Bytes[ndx]);
  556.     ndx++;
  557.     }
  558. }
  559.  
  560. void
  561. DumpCodeList(InstListVia_t Codes, MPWListVia_t Records)
  562. {
  563.     InstVia_t                       cur;
  564.     unsigned short                  RecordID;
  565.     char                            LastCodeSymbol[64];
  566.     int                             ndx;
  567.     unsigned char                   FlagsByte = 0;
  568.     MPWSeg = 0;
  569.     CODEContentsBuffer = Ealloc(MAXCONTENTS);
  570.     CODEContentsIndex = 0;
  571.     DATAContentsBuffer = Ealloc(MAXCONTENTS);
  572.     DATAContentsIndex = 0;
  573.     if (!(Codes && Records)) {
  574.     CodegenError("Bad instruction list");
  575.     }
  576.     /*
  577.      * Process every instruction in Codes, generating MPW OBJ records as
  578.      * necessary, inserting them into Records.
  579.      */
  580.     Pass = 1;
  581.     while (Pass <= 2) {
  582.     Pc = 0;
  583.     cur = Via(Codes)->head;
  584.     while (cur) {
  585.         switch (Via(cur)->OP) {
  586.         case M68op_STARTCOMMENT:
  587.         case M68op_TEXTCOMMENT:
  588.         case M68op_PLAINTEXTCOMMENT:
  589.         case M68op_COMMENT:
  590.         case M68op_CRCOMMENT:
  591.         /* We currently do nothing with comments */
  592.         break;
  593.         case M68op_MPWSEG:
  594.         CurMPWSegNum = NameID(OBJNameList, Via(GetLocLabel(Via(cur)->left))->name, 0, 1, Records);
  595.         break;
  596.         case M68op_CODELABEL:
  597. #ifdef OLDMEM
  598.         HLock((Handle) GetLocLabel(Via(cur)->left));
  599. #endif
  600.         RecordID = NameID(OBJNameList, Via(GetLocLabel(Via(cur)->left))->name, 0, 1, Records);
  601.         strcpy(LastCodeSymbol, Via(GetLocLabel(Via(cur)->left))->name);
  602.         FlagsByte = GetModuleFlags(Via(GetLocLabel(Via(cur)->left))->name);
  603.         CodeModule(FlagsByte, RecordID, CurMPWSegNum, Records);
  604. #ifdef OLDMEM
  605.         HUnlock((Handle) GetLocLabel(Via(cur)->left));
  606. #endif
  607.         break;
  608.         case M68op_STRINGLABEL:
  609. #ifdef OLDMEM
  610.         HLock((Handle) GetLocLabel(Via(cur)->left));
  611. #endif
  612.         RecordID = NameID(OBJNameList, Via(GetLocLabel(Via(cur)->left))->name, 1, 1, Records);
  613. #ifdef OLDMEM
  614.         HUnlock((Handle) GetLocLabel(Via(cur)->left));
  615. #endif
  616.         FlagsByte = 1;
  617.         DataModule(FlagsByte, RecordID, 0, Records);
  618.         break;
  619.         case M68op_DATALABEL:
  620. #ifdef OLDMEM
  621.         HLock((Handle) GetLocLabel(Via(cur)->left));
  622. #endif
  623.         RecordID = NameID(OBJNameList, Via(GetLocLabel(Via(cur)->left))->name, 0, 1, Records);
  624.         FlagsByte = GetModuleFlags(Via(GetLocLabel(Via(cur)->left))->name);
  625. #ifdef OLDMEM
  626.         HUnlock((Handle) GetLocLabel(Via(cur)->left));
  627. #endif
  628.         DataModule(FlagsByte, RecordID, 0, Records);    /* 0 is size
  629.                                  * specification - it
  630.                                  * will be set later
  631.                                  * using a Size record
  632.                                  * generated from op_DS */
  633.         break;
  634.         case M68op_LCOMM:
  635. #ifdef OLDMEM
  636.         HLock((Handle) GetLocLabel(Via(cur)->left));
  637. #endif
  638.         RecordID = NameID(OBJNameList, Via(GetLocLabel(Via(cur)->left))->name, 0, 0, Records);
  639. #ifdef OLDMEM
  640.         HUnlock((Handle) GetLocLabel(Via(cur)->left));
  641. #endif
  642.         DataModule(1, RecordID, GetLocConstant(Via(cur)->right), Records);
  643.         break;
  644.         case M68op_COMM:
  645. #ifdef OLDMEM
  646.         HLock((Handle) GetLocLabel(Via(cur)->left));
  647. #endif
  648.         RecordID = NameID(OBJNameList, Via(GetLocLabel(Via(cur)->left))->name, 0, 1, Records);
  649. #ifdef OLDMEM
  650.         HUnlock((Handle) GetLocLabel(Via(cur)->left));
  651. #endif
  652.         DataModule(9, RecordID, GetLocConstant(Via(cur)->right), Records);
  653.         break;
  654.         case M68op_XREF:
  655. #ifdef OLDMEM
  656.         HLock((Handle) GetLocLabel(Via(cur)->left));
  657. #endif
  658.         MPW_Dictionary(FlagsByte, Via(GetLocLabel(Via(cur)->left))->name, 0, Records);
  659. #ifdef OLDMEM
  660.         HUnlock((Handle) GetLocLabel(Via(cur)->left));
  661. #endif
  662.         /*
  663.          * The 0 is for xref as opposed to Defined
  664.          */
  665.         break;
  666.         case M68op_DEFSEG:
  667. #ifdef OLDMEM
  668.         HLock((Handle) GetLocLabel(Via(cur)->left));
  669. #endif
  670.         MPW_Dictionary(FlagsByte, Via(GetLocLabel(Via(cur)->left))->name, 1, Records);
  671. #ifdef OLDMEM
  672.         HUnlock((Handle) GetLocLabel(Via(cur)->left));
  673. #endif
  674.         /*
  675.          * The 1 is for Defined as opposed to xref
  676.          */
  677.         break;
  678.         case M68op_XDEF:
  679. #ifdef OLDMEM
  680.         HLock((Handle) GetLocLabel(Via(cur)->left));
  681. #endif
  682.         MPW_Dictionary(FlagsByte, Via(GetLocLabel(Via(cur)->left))->name, 1, Records);
  683. #ifdef OLDMEM
  684.         HUnlock((Handle) GetLocLabel(Via(cur)->left));
  685. #endif
  686.         /*
  687.          * The 1 is for Defined as opposed to xref
  688.          */
  689.         break;
  690.         case M68op_BSEG:
  691.         case M68op_DSEG:
  692.         MPWSeg = 1;
  693.         break;
  694.         case M68op_CSEG:
  695.         MPWSeg = 0;
  696.         break;
  697.         case M68op_DS:
  698.         MPW_Size(MPWSeg, GetLocConstant(Via(cur)->left), Records);
  699.         break;
  700.         case M68op_DC:
  701.         Via(cur)->Address = Pc;
  702.         if (GetLocAM(Via(cur)->left) == M68am_AbsLong) {
  703.             switch (Via(cur)->SZ) {
  704.             case M68sz_byte:
  705.             AddContentsByte(GetLocConstant(Via(cur)->left));
  706.             Pc++;
  707.             break;
  708.             case M68sz_word:
  709.             AddContentsWord(GetLocConstant(Via(cur)->left));
  710.             Pc += 2;
  711.             break;
  712.             case M68sz_long:
  713.             AddContentsLong(GetLocConstant(Via(cur)->left));
  714.             Pc += 4;
  715.             break;
  716.             default:
  717.             Gen68Error("Bad DC size");
  718.             break;
  719.             }
  720.         } else {
  721.             int                             id;
  722.             /*
  723.              * We need to put a Reference record.  We need the ID of
  724.              * the module we are referencing.  We also need the
  725.              * offset, so we need the value of the correct
  726.              * ContentsIndex, and we need to decide what the flags
  727.              * will be.
  728.              */
  729.             switch (Via(cur)->SZ) {
  730.             case M68sz_byte:
  731.             AddContentsByte(0);
  732.             Pc++;
  733.             break;
  734.             case M68sz_word:
  735. #ifdef OLDMEM
  736.             HLock((Handle) GetLocLabel(Via(cur)->left));
  737. #endif
  738.             id = NameID(OBJNameList, Via(GetLocLabel(Via(cur)->left))->name, 0, 0, Records);
  739. #ifdef OLDMEM
  740.             HUnlock((Handle) GetLocLabel(Via(cur)->left));
  741. #endif
  742.             MPW_Reference(128 + 16 + MPWSeg, id, MPWSeg ? CODEContentsIndex : DATAContentsIndex, Records);
  743.             AddContentsWord(0);
  744.             Pc += 2;
  745.             break;
  746.             case M68sz_long:
  747. #ifdef OLDMEM
  748.             HLock((Handle) GetLocLabel(Via(cur)->left));
  749. #endif
  750.             id = NameID(OBJNameList, Via(GetLocLabel(Via(cur)->left))->name, 0, 0, Records);
  751. #ifdef OLDMEM
  752.             HUnlock((Handle) GetLocLabel(Via(cur)->left));
  753. #endif
  754.             MPW_Reference(128 + MPWSeg, id, MPWSeg ? CODEContentsIndex : DATAContentsIndex, Records);
  755.             AddContentsLong(0);
  756.             Pc += 4;
  757.             break;
  758.             default:
  759.             Gen68Error("Bad DC size");
  760.             break;
  761.             }
  762.         }
  763.         break;
  764.         case M68op_MBG:
  765.         /* Here we add MacsBug symbol information */
  766.         AddContentsByte(0x80 + strlen(LastCodeSymbol));
  767.         Pc++;
  768.         ndx = 0;
  769.         while (LastCodeSymbol[ndx]) {
  770.             AddContentsByte(LastCodeSymbol[ndx++]);
  771.             Pc++;
  772.         }
  773.         if (CODEContentsIndex % 2)
  774.             AddContentsByte(0);    /* align even */
  775.         AddContentsByte(0);    /* size of literals */
  776.         AddContentsByte(0);
  777.         Pc += 3;
  778.         break;
  779.         case M68op_EVEN:
  780.         WordAlignContents();
  781.         break;
  782.         default:
  783.         /*
  784.          * The default here is an instruction of some kind.  We pass
  785.          * this to another routine to handle all instructions that
  786.          * come in sequence, generating Contents and Reference
  787.          * records appropriately.  When that routine finds a
  788.          * directive, control comes back to this routine.
  789.          */
  790.         process(cur);
  791.         AddtoContents(cur);
  792.         break;
  793.         }
  794.         if (cur)
  795.         cur = Via(cur)->next;
  796.     }
  797.     Pass++;
  798.     }
  799.     FlushCode(Records);
  800.     FlushData(Records);
  801.     Efree(CODEContentsBuffer);
  802.     Efree(DATAContentsBuffer);
  803. }
  804.  
  805. OSType
  806. MakeOSType(char *d)
  807. {
  808.     OSType                          result;
  809.     result = d[0] << 24;
  810.     result |= d[1] << 16;
  811.     result |= d[2] << 8;
  812.     result |= d[3];
  813.     return result;
  814. }
  815.  
  816. short 
  817. InitOMF(InstListVia_t Codes, char *fname, short volrefnum, long dirID)
  818. {
  819.     MPWRecordVia_t                  cur;
  820.     int                             totalwritten;
  821.     OSErr                           bad;
  822.     char                            OBJName[64];
  823.     short                           filenum;
  824.     strcpy(OBJName, fname);
  825.     c2pstr(OBJName);
  826.     OBJName[OBJName[0]] = 'o';
  827.     totalwritten = 0;
  828.     bad = HDelete(volrefnum, dirID, OBJName);
  829.     if (bad != -43)
  830.         UserFileError(bad);
  831.     Pass = 0;
  832.     if (NumErrors)
  833.     return 0;
  834.     GlobalRecords = RawMPWList();
  835.     OBJNameList = RawMPWDictList();
  836.     MPW_First(0, 2, GlobalRecords);    /* the 2 will be a 3 if SADE info is
  837.                      * included */
  838.     MPW_Comment("Created by Harvest C", GlobalRecords);
  839.     bad = HCreate(volrefnum, dirID, OBJName, MakeOSType("Jn15"), MakeOSType("OBJ "));
  840.     UserFileError(bad);
  841.     if (!bad) {
  842.     bad = HOpen(volrefnum, dirID, OBJName, 2, &filenum);
  843.     UserFileError(bad);
  844.     }
  845.     return filenum;
  846. }
  847.  
  848. void
  849. FlushOMF(short filenum)
  850. {
  851.     MPWRecordVia_t                  cur;
  852.     int                             totalwritten = 0;
  853.     OSErr                           bad;
  854.     if (GlobalRecords) {
  855.     cur = Via(GlobalRecords)->head;
  856.     while (cur) {
  857.         long                            count;
  858.         count = Via(cur)->recsize;
  859. #ifdef OLDMEM
  860.         HLock((Handle) Via(cur)->theRecord);
  861. #endif
  862.         bad = FSWrite(filenum, &count, (char *) Via(Via(cur)->theRecord));
  863. #ifdef OLDMEM
  864.         HUnlock((Handle) Via(cur)->theRecord);
  865. #endif
  866.         UserFileError(bad);
  867.         totalwritten += count;
  868.         if (totalwritten % 2) {
  869.         char                            padbyte[2];
  870.         long                            count2;
  871.         totalwritten++;
  872.         count2 = 1;
  873.         padbyte[0] = 0;
  874.         bad = FSWrite(filenum, &count2, padbyte);
  875.         UserFileError(bad);
  876.         }
  877.         cur = Via(cur)->next;
  878.     }
  879.     KillRecordsList(GlobalRecords);
  880.     }
  881. }
  882.  
  883. void
  884. FinishOMF(short filenum)
  885. {
  886.     MPWRecordVia_t                  cur;
  887.     int                             totalwritten;
  888.     OSErr                           bad;
  889.     MPW_Last(GlobalRecords);
  890.  
  891.     FlushOMF(filenum);
  892.  
  893.     bad = FSClose(filenum);
  894.     UserFileError(bad);
  895.  
  896.     Efree(GlobalRecords);
  897.     KillDictList(OBJNameList);
  898. }
  899.  
  900. void
  901. GenerateOBJ(InstListVia_t Codes, char *fname, short volrefnum, long dirID)
  902. {
  903.     short                           filenum;
  904.     filenum = InitOMF(Codes, fname, volrefnum, dirID);
  905.     DumpCodeList(Codes, GlobalRecords);
  906.     FlushOMF(filenum);
  907.     FinishOMF(filenum);
  908. }
  909.